package wortubung.lang.fr;

import java.io.IOException;
import java.util.Properties;

import org.json.JSONArray;

import wortubung.core.LANG;
import wortubung.inflection.CONJUGATION;
import wortubung.inflection.ConjugationResult;
import wortubung.inflection.ConjugationSet;
import wortubung.inflection.VerbConjugation;
import wortubung.inflection.UnknownConjugationException;
import wortubung.lang.ConjugatorBase;
import wortubung.util.LatinScript;

import static wortubung.lang.LanguageManager.*;
import static wortubung.lang.fr.ConjugueurUtil.*;
import static wortubung.util.CommonUtils.*;

/**
 * Singleton
 */
public class Conjugueur extends ConjugatorBase {

	public static final Conjugueur defaultConjugator = new Conjugueur();

	static {
		defaultConjugator.readInitFiles(FR_EXCEPTIONS_VERBE_FILE, FR_CONJUGAISONS_AS_IS_FILE);
	}
	
	public static VerbConjugation conjugate(String verb) {
		return defaultConjugator.getConjugation(verb);
	}

	@Override public LANG getLanguage() { return LANG.fr; }

	@Override
	protected void furtherInit(Properties props) throws IOException {
		// Read irregulars by-rule from the resource (JSON) file
		String jsonStr = readFileFromCPAsString(FR_CONJUGAISONS_BY_RULE_FILE);
		JSONArray jsonArr = new JSONArray(jsonStr);
		for (int i=0; i<jsonArr.length(); ++i)
			addIrregulerConjugation(ConjugueurIrregulier.getRuleFromJSON(jsonArr.getJSONObject(i)));
	}

	@Override
	protected void postProcess(VerbConjugation result, String verbSuffix) {
		ConjugationResult ret = (ConjugationResult)result;
		if (verbSuffix.endsWith("er"))
			ret.setRefIndex1(-1);
		else if (verbSuffix.endsWith("ir"))
			ret.setRefIndex1(-2);
		else if (verbSuffix.endsWith("re"))
			ret.setRefIndex1(-3);
		
		if (verbSuffix.endsWith("ayer")) {
			ConjugationSet cs =
					new ConjugationSet(ret, participle(verbSuffix, true), participle(verbSuffix, false));
			for (CONJUGATION type : CONJUGATION.forLanguage(LANG.fr)) {
				if (type.getDisplay(LANG.fr) == null)
					continue;
				String[] conj = conjugate(verbSuffix, type, false);
				if (conj != null)
					cs.add(type, conj);
			}
			ret.addConjugationSet(cs);
		}
	}

	@Override
	protected String participle(String verbeSuffix, boolean isPresent) {
		String participeRacine = null;
		String racine = chopRight(verbeSuffix, 2);
		if (isPresent) {
			if (verbeSuffix.endsWith("er"))
				participeRacine = phonetique(racine, "ant", true);
			else if (verbeSuffix.endsWith("ir"))
				participeRacine = racine + "issant";
			else if (verbeSuffix.endsWith("cre"))  // pour "vaincre"
				participeRacine = chopRight(verbeSuffix, 3) + "quant";
			else if (verbeSuffix.endsWith("re"))
				participeRacine = chopRight(verbeSuffix, 2) + "ant";
		} else {
			if (verbeSuffix.endsWith("er"))
				participeRacine =  phonetique(racine, 'é', true);
			else if (verbeSuffix.endsWith("ir")) {
				try {
					if (!LatinScript.isVowel(verbeSuffix.charAt(verbeSuffix.length()-3)))
						participeRacine = racine + 'i';
				} catch(Exception e) {}
			}
			else if (verbeSuffix.endsWith("re")) {
				try {
					char c = verbeSuffix.charAt(verbeSuffix.length()-3);
					if (c == 'd' || c == 'p' || c == 't' || c == 'c')
						participeRacine = racine + 'u';
					else {
						// irregulier
						if (racine.endsWith("i"))
							participeRacine = racine;
						else
							participeRacine = racine + 'i';
					}
				} catch(Exception e) {}
			}
		}

		if (participeRacine == null)
			UnknownConjugationException.badVerb(verbeSuffix);

		return participeRacine;
	}

	/**
	 * 
	 * @return String[6]: je, tu, il/elle, nous, vous, ils/elles
	 */
	protected String[] conjugate(String verbeSuffix, CONJUGATION type, boolean fairePhonetique) {
		String conjuguerRacines[] = null;
		switch (type) {
		case IMPERATIVE:  return imperatif(verbeSuffix, fairePhonetique);
		case FUTURE:      return apposerIndiceFuturConditionnel(verbeSuffix, fairePhonetique, true);
		case CONDITIONAL: return apposerIndiceFuturConditionnel(verbeSuffix, fairePhonetique, false);
		default:
    		if (verbeSuffix.endsWith("er")) {
    			conjuguerRacines = conjuguerER(verbeSuffix, type, fairePhonetique);
    		} else if (verbeSuffix.endsWith("ir")) {
    			try {
    				if (!LatinScript.isVowel(verbeSuffix.charAt(verbeSuffix.length()-3)))
    					conjuguerRacines = conjuguerIR(verbeSuffix, type);
    			} catch(Exception e) {}
    		} else if (verbeSuffix.endsWith("re")) {
    			try {
    				char ch = verbeSuffix.charAt(verbeSuffix.length() - 3);
    				if (ch == 'p' || ch == 't' || ch == 'd' || ch == 'c')
    					conjuguerRacines = conjuguerRE(verbeSuffix, type);
    			} catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
		}
		if (conjuguerRacines == null)
			UnknownConjugationException.badVerb(verbeSuffix);

		return conjuguerRacines;
	}

	private String[] imperatif(String verbeSuffix, boolean fairePhonetique) {
		String[] resulte = conjugate(verbeSuffix, CONJUGATION.PRESENT, fairePhonetique);
		imperatifDePresent(resulte);
		return resulte;
	}
}
